﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace SecTool.Core
{
    [Serializable]
    public class Document
    {
        public Document()
        {
        }

        public Document(Document document)
        {
            this.Payload = document.Payload;
            this.Signature = document.Signature;
            this.Key = document.Key;
            this.IV = document.IV;
            this.Algorithm = document.Algorithm;
            this.HashAlgorithm = document.HashAlgorithm;
            this.Author = document.Author;
            this.Recipient = document.Recipient;
            this.Filename = document.Filename;
        }

        /// <summary>
        /// Symmetric algorithm used
        /// </summary>
        public Crypto.SymmetricAlgorithm Algorithm { get; set; }

        /// <summary>
        /// Hash algorithm used
        /// </summary>
        public Crypto.HashAlgorithm HashAlgorithm { get; set; }

        /// <summary>
        /// Document contents
        /// </summary>
        public byte[] Payload { get; set; }

        /// <summary>
        /// Payload hash value
        /// </summary>
        public byte[] Signature { get; set; }

        /// <summary>
        /// Key for symmetric algorithm
        /// </summary>
        public byte[] Key { get; set; }

        /// <summary>
        /// Initialization vector for symmetric algorithm
        /// </summary>
        public byte[] IV { get; set; }

        /// <summary>
        /// Author of the document
        /// </summary>
        public string Author { get; set; }

        /// <summary>
        /// filename
        /// </summary>
        public string Filename { get; set; }

        public bool Encrypted
        {
            get
            {
                return Key != null && Key.Length > 0;
            }
        }

        public bool CanBeEncrypted
        {
            get
            {
                return this.HasPayload
                    && !this.Encrypted 
                    && this.Algorithm != Core.Crypto.SymmetricAlgorithm.None;
            }
        }


        public bool UserCanDecrypt(string username)
        {
            return this.HasPayload
                && this.Encrypted
                && this.Algorithm != Core.Crypto.SymmetricAlgorithm.None
                && this.Recipient == username;            
        }

        public bool Signed
        {
            get
            {
                return Signature != null && Signature.Length > 0;
            }
        }

        public bool CanBeSigned
        {
            get
            {
                return this.HasPayload && !this.Signed;
            }
        }

        public bool HasPayload
        {
            get
            {
                return Payload != null && Payload.Length > 0;
            }
        }
        /// <summary>
        /// Recipient of the document
        /// </summary>
        public string Recipient { get; set; }

        public void SerializeToFile(string fileName)
        {
            using (System.IO.FileStream stream = new System.IO.FileStream(fileName, System.IO.FileMode.Create))
            {
                this.SerializeToStream(stream);
                //serializer.Serialize(stream, this);
            }
        }

        public void SerializeToStream(Stream stream)
        {
            var serializer = new System.Xml.Serialization.XmlSerializer(this.GetType());

            serializer.Serialize(stream, this);
        }

        public static Document Deserialize(System.IO.Stream stream)
        {
            var serializer = new System.Xml.Serialization.XmlSerializer(typeof(Document));

            return serializer.Deserialize(stream) as Document;
        }
    }
}